﻿

#region Using Statements

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using System.Threading;
using System.ComponentModel;
using System.Reflection;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Design;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

using Freeform;
using FGame = Freeform.Game;
using XGame = Microsoft.Xna.Framework.Game;
using FComponent = Freeform.Component;

#endregion


namespace Freeform
{
    /// <summary>
    /// Basically every class in the engine extends from Component. Each component carries a unique ID so that they can be referenced
    /// remotely via network messages or so that closed loop references can be maintained when a game is serialized to persistant storage.
    /// </summary>
    public class Component
    {

        #region Members

        /// <summary>
        /// Gets the ID of this component.
        /// </summary>
        public UInt64 ComponentID { get; private set; }


        /// <summary>
        /// Gets the next ID to be issued.
        /// </summary>
        private static UInt64 NextID { get; set; }


        /// <summary>
        /// Gets a reference to the game that this component belongs to.
        /// </summary>
        public IGame Game { get; private set; }


        /// <summary>
        /// Gets whether or not this entity has been disposed.
        /// </summary>
        public Boolean IsDisposed { get; private set; }


        /// <summary>
        /// Gets or sets whether or not the component is currently loaded.
        /// </summary>
        public Boolean IsLoaded { get; set; }


        /// <summary>
        /// Gets or sets whether this entity is currently enabled (receives updates.)
        /// </summary>
        public Boolean IsEnabled { get; set; }


        /// <summary>
        /// Gets or sets the priority of the component, which affects its update order in the component lists if Priority sorting is enabled.
        /// </summary>
        public Single Priority { get; set; }


        /// <summary>
        /// Gets the list that this component belongs to.
        /// </summary>
        public ComponentList List { get; private set; }


        /// <summary>
        /// Gets or sets how long this component has been active for (in milliseconds.)
        /// </summary>
        public UInt32 Age { get; set; }

        #endregion


        #region Init

        /// <summary>
        /// Creates a new component for the game.
        /// </summary>
        /// <param name="game">The game.</param>
        public Component(ComponentList List)
        {
            this.List = List;
            Game = List.Game;
            ComponentID = NextID++;
            IsEnabled = true;
            IsLoaded = true;
            Game.FreeformComponents.Add(ComponentID, this);
            List.Library.Add(ComponentID, this);
        }

        #endregion


        #region Update

        /// <summary>
        /// Allows the component to update itself.
        /// </summary>
        /// <param name="Time">Provides a snapshot of timing values.</param>
        public virtual void Update(GameTime Time)
        {
            Age += (UInt32)Time.ElapsedGameTime.Milliseconds;
        }

        #endregion


        #region Dispose

        /// <summary>
        /// Disposes the entity and removes it from the world.
        /// </summary>
        public void Dispose()
        {
            if (!IsDisposed)
                OnDispose();
        }


        /// <summary>
        /// Actions to carry out upon disposal.
        /// </summary>
        protected virtual void OnDispose() 
        {
            Game.FreeformComponents.Remove(ComponentID);
            List.Library.Remove(ComponentID);
            IsDisposed = true;
        }

        #endregion

    }
}
